#include "stream/event.h"
#include <thread>
#include <fstream>
#include <string>
#include <sstream>
#include "liteai/yolo.h"
#include "ssiot/httplib.h"
#include "ssiot/ssiot.h"
#include "ssiot/msgbus.h"
#include "ssiot/json.hpp"


Event::Event()
{
	std::thread* t = new std::thread(&Event::Run, this);
}

Event::~Event()
{

}

void Event::Run() 
{
	while (true)
	{
		DetectObjsInfo* objs = queue_.wait_and_pop();

		std::string img = UploadFile(objs->imgfile);
		if (img.length() == 0 ) {
			delete objs;
			continue;
		}

		std::string rec = UploadFile(objs->recfile);
		if (rec.length() == 0) {
			delete objs;
			continue;
		}

		nlohmann::json evt;
		evt["motion"]["timestamp"] = objs->timestamp;
		evt["motion"]["timescost"] = objs->times;
		evt["motion"]["image"] = img;
		evt["motion"]["record"] = rec;
		evt["motion"]["obj"] = objs->objs[0];

		char buf[256];
		memset(buf, 0, 256);
		for (int i = 0; i < objs->objs.size(); i++) {
			sprintf(buf + strlen(buf), "%s:%.2f;\n", objs->objs[i].c_str(), objs->scores[i]);
		}

		evt["motion"]["info"] = buf;

		SSIoT::INST()->msgbug()->Publish(IoTMsg(SSIOT_SENSOR, "", "", evt));

		remove(objs->imgfile.c_str());
		remove(objs->recfile.c_str());

		delete objs;
	}
}

void  Event::Frie(DetectObjsInfo* info)
{
	queue_.push(info);
}

std::string Event::UploadFile(std::string filename) 
{
	std::string addr = SSIoT::INST()->Service();

	httplib::Client cli(addr, 9000);

	std::ifstream fin(filename, std::ios::binary);

	std::ostringstream os;
	os << fin.rdbuf();

	std::string content = os.str();
	std::cout << content.length() << std::endl;
	fin.close();

	httplib::MultipartFormDataItems items = {
		{"file", content, filename, "application/octet-stream"},
	};

	cli.set_default_headers({
		{ "Authentication", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTMxMzg4OTUsIm9yaWdfaWF0IjoxNjc3MTM4ODk1LCJ1c2VybmFtZSI6InpvdXFxeiJ9.26DpLmyg33MaYdfpd0baDgYMFdfAjm4qhDhflcwosI4" }
	});

	auto res = cli.Post("/api/file/upload", items);

	if (res->status != 200) {
		fprintf(stderr, "post file error %d. %s", res->status, filename.c_str());
		return "";
	}

	nlohmann::json obj = nlohmann::json::parse(res->body);

	if (obj["code"] != 200) {
		fprintf(stderr, "uploadfile error %s", filename.c_str());
		return "";
	}

	return (std::string("/api/file/download/") + std::string(obj["result"]));
}
